package org.aspire.core.loop;

import org.aspire.core.sys.GSystem;

/******************************************************************************
 * A loop controller implementation derived from SystemTimer class of GTGE.
 * <p>
 * It uses J2SE System class to retrieve system current time.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public class StandardLoopController extends LoopController {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================

	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * Hold drift on Thread.sleep() method.
	 *************************************************************************/
	protected long overSleep;
	
	/**************************************************************************
	 * Amount of time in millisecond that the thread will sleep.
	 *************************************************************************/
	protected long sleepTime;
	
	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Construct a new standard loop controller.
	 *************************************************************************/
	public StandardLoopController() {
		super();
		this.lastCall = GSystem.getTime();
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================

	// ========================================================================
	// Override Methods
	// ========================================================================

	@Override
	public void sleep() {
		long end = GSystem.getTime();
		
		if(this.regulate) {
			if(this.sleepTime > 0) {
				try {
					Thread.sleep(this.sleepTime);
				} catch(InterruptedException e) {
					
				}
				
				this.overSleep = (GSystem.getTime() - end) - this.sleepTime;
			} else {
				try {
					Thread.sleep(1);
				} catch(InterruptedException e) {
					
				}
				
				this.overSleep = 0;
			}
		}
	}
	
	@Override
	public void tick() {
		long difference = GSystem.getTime() - this.lastCall;
		this.sleepTime = ((this.resolution / this.fps) - difference)
				- this.overSleep;
		
		this.fpsCounter.calculateFPS();
		
		long end = GSystem.getTime();
		this.duration = end - this.lastCall;
		this.lastCall = end;
	}

	// ========================================================================
	// Methods
	// ========================================================================

	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}